home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 22 / AACD 22.iso / AACD / Online / Apache / lib / php / DB / oci8.php < prev    next >
Encoding:
PHP Script  |  2001-03-06  |  11.2 KB  |  474 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: James L. Pine <jlp@valinux.com>                             |
  17. // |                                                                      |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // Database independent query interface definition for PHP's Oracle 8
  21. // call-interface extension.
  22. //
  23.  
  24. //
  25. // be aware...  OCIError() only appears to return anything when given a
  26. // statement, so functions return the generic DB_ERROR instead of more
  27. // useful errors that have to do with feedback from the database.
  28. //
  29.  
  30.  
  31. require_once 'DB/common.php';
  32.  
  33. class DB_oci8 extends DB_common {
  34.     // {{{ properties
  35.  
  36.     var $connection;
  37.     var $phptype, $dbsyntax;
  38.     var $select_query = array();
  39.     var $prepare_types = array();
  40.     var $autoCommit = 1;
  41.     var $last_stmt = false;
  42.  
  43.     // }}}
  44.  
  45.     // {{{ constructor
  46.  
  47.     function DB_oci8() {
  48.         $this->phptype = 'oci8';
  49.         $this->dbsyntax = 'oci8';
  50.         $this->features = array(
  51.             'prepare' => false,
  52.             'pconnect' => true,
  53.             'transactions' => true
  54.         );
  55.         $this->errorcode_map = array();
  56.     }
  57.  
  58.     // }}}
  59.  
  60.     // {{{ connect()
  61.  
  62.     /**
  63.      * Connect to a database and log in as the specified user.
  64.      *
  65.      * @param $dsn the data source name (see DB::parseDSN for syntax)
  66.      * @param $persistent (optional) whether the connection should
  67.      *        be persistent
  68.      *
  69.      * @return int DB_OK on success, a DB error code on failure
  70.      */
  71.     function connect(&$dsn, $persistent = false) {
  72.         if (is_array($dsn)) {
  73.             $dsninfo = &$dsn;
  74.         } else {
  75.             $dsninfo = DB::parseDSN($dsn);
  76.         }
  77.         if (!$dsninfo || !$dsninfo['phptype']) {
  78.             return $this->raiseError();
  79.         }
  80.         $user = $dsninfo['username'];
  81.         $pw = $dsninfo['password'];
  82.         $hostspec = $dsninfo['hostspec'];
  83.  
  84.         $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
  85.         if ($user && $pw && $hostspec) {
  86.             $conn = $connect_function($user,$pw,$hostspec);
  87.         } elseif ($user && $pw) {
  88.             $conn = $connect_function($user,$pw);
  89.         } else {
  90.             $conn = false;
  91.         }
  92.         if ($conn == false) {
  93.             return $this->raiseError();
  94.         }
  95.         $this->connection = $conn;
  96.         return DB_OK;
  97.     }
  98.  
  99.     // }}}
  100.     // {{{ disconnect()
  101.  
  102.     /**
  103.      * Log out and disconnect from the database.
  104.      *
  105.      * @return bool TRUE on success, FALSE if not connected.
  106.      */
  107.     function disconnect() {
  108.         return OCILogOff($this->connection);
  109.     }
  110.  
  111.     // }}}
  112.     // {{{ query()
  113.  
  114.  
  115.     /**
  116.      * Send a query to the database and return the results as a DB_result object.
  117.      *
  118.      * @param $query the SQL query
  119.      *
  120.      * @return object a DB_result object on success, a DB error code
  121.      * on failure
  122.      */
  123.     function &query($query) {
  124.         $this->last_query = $query;
  125.         $result = OCIParse($this->connection, $query);
  126.         if (!$result) {
  127.             return $this->raiseError();
  128.         }
  129.         if ($this->autoCommit) {
  130.             $success=OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
  131.         }
  132.         else {
  133.             $success=OCIExecute($result,OCI_DEFAULT);
  134.         }
  135.         if (!$success) {
  136.             return $this->raiseError();
  137.         }
  138.         $this->last_stmt=$result;
  139.         // Determine which queries that should return data, and which
  140.         // should return an error code only.
  141.         if (preg_match('/(SELECT|SHOW)/i', $query)) {
  142.             $resultObj = new DB_result($this, $result);
  143.             return $resultObj;
  144.         } else {
  145.             return DB_OK;
  146.         }
  147.     }
  148.  
  149.     // }}}
  150.     // {{{ simpleQuery()
  151.  
  152.     /**
  153.      * Send a query to oracle and return the results as an oci8 resource
  154.      * identifier.
  155.      *
  156.      * @param $query the SQL query
  157.      *
  158.      * @return int returns a valid oci8 result for successful SELECT
  159.      * queries, DB_OK for other successful queries.  A DB error code
  160.      * is returned on failure.
  161.      */
  162.     function simpleQuery($query) {
  163.         $this->last_query = $query;
  164.         $result = OCIParse($this->connection, $query);
  165.         if (!$result) {
  166.             return $this->raiseError();
  167.         }
  168.         if ($this->autoCommit) {
  169.             $success=OCIExecute($result,OCI_COMMIT_ON_SUCCESS);
  170.         }
  171.         else {
  172.             $success=OCIExecute($result,OCI_DEFAULT);
  173.         }
  174.         if (!$success) {
  175.             return $this->raiseError();
  176.         }
  177.         $this->last_stmt=$result;
  178.         // Determine which queries that should return data, and which
  179.         // should return an error code only.
  180.         if (preg_match('/(SELECT|SHOW)/i', $query)) {
  181.             return $result;
  182.         } else {
  183.             return DB_OK;
  184.         }
  185.     }
  186.  
  187.     // }}}
  188.     // {{{ fetchRow()
  189.  
  190.     /**
  191.      * Fetch a row and return as array.
  192.      *
  193.      * @param $result oci8 result identifier
  194.      * @param $fetchmode how the resulting array should be indexed
  195.      *
  196.      * @return int an array on success, a DB error code on failure, NULL
  197.      *             if there is no more data
  198.      */
  199.     function &fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT) {
  200.         if ($fetchmode == DB_FETCHMODE_DEFAULT) {
  201.             $fetchmode = $this->fetchmode;
  202.         }
  203.         if ($fetchmode & DB_FETCHMODE_ASSOC) {
  204.             $moredata=OCIFetchInto($result,$row,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
  205.         } else {
  206.             $moredata=OCIFetchInto($result,$row,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
  207.         }
  208.         if (!$row) {
  209.             return $this->raiseError();
  210.         }
  211.         if ($moredata==NULL) {
  212.             return NULL;
  213.         }
  214.         return $row;
  215.     }
  216.  
  217.     // }}}
  218.     // {{{ fetchInto()
  219.  
  220.     /**
  221.      * Fetch a row and insert the data into an existing array.
  222.      *
  223.      * @param $result oci8 result identifier
  224.      * @param $arr (reference) array where data from the row is stored
  225.      * @param $fetchmode how the array data should be indexed
  226.      *
  227.      * @return int DB_OK on success, a DB error code on failure
  228.      */
  229.     function fetchInto($result, &$arr, $fetchmode = DB_FETCHMODE_DEFAULT) {
  230.         if ($fetchmode == DB_FETCHMODE_DEFAULT) {
  231.             $fetchmode = $this->fetchmode;
  232.         }
  233.         if ($fetchmode & DB_FETCHMODE_ASSOC) {
  234.             $moredata=OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS);
  235.         } else {
  236.             $moredata=OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS);
  237.         }
  238.         if (!($arr && $moredata)) {
  239.             return $this->raiseError();
  240.         }
  241.         return DB_OK;
  242.     }
  243.  
  244.     // }}}
  245.     // {{{ freeResult()
  246.  
  247.     /**
  248.      * Free the internal resources associated with $result.
  249.      *
  250.      * @param $result oci8 result identifier or DB statement identifier
  251.      *
  252.      * @return bool TRUE on success, FALSE if $result is invalid
  253.      */
  254.     function freeResult($result) {
  255.         if (is_resource($result)) {
  256.             return OCIFreeStatement($result);
  257.         }
  258.         if (!isset($this->prepare_tokens[$result])) {
  259.             return false;
  260.         }
  261.         unset($this->prepare_tokens[$result]);
  262.         unset($this->prepare_types[$result]);
  263.         return true; 
  264.     }
  265.  
  266.     // }}}
  267.     // {{{ numCols()
  268.  
  269.     /**
  270.      * Get the number of columns in a result set.
  271.      *
  272.      * @param $result oci8 result identifier
  273.      *
  274.      * @return int the number of columns per row in $result
  275.      */
  276.     function numCols($result) {
  277.         $cols = OCINumCols($result);
  278.         if (!$cols) {
  279.             return $this->raiseError();
  280.         }
  281.         return $cols;
  282.     }
  283.  
  284.     // }}}
  285.     // {{{ errorNative()
  286.  
  287.     /**
  288.      * Get the native error code of the last error (if any) that occured
  289.      * on the current connection.  This does not work, as OCIError does
  290.      * not work unless given a statement.  If OCIError does return
  291.      * something, so will this.
  292.      *
  293.      * @return int native oci8 error code
  294.      */
  295.     function errorNative() {
  296.         $error=OCIError($this->connection);
  297.         if (is_array($error)) {
  298.             return $error['code'];
  299.         }
  300.         return false;
  301.     }
  302.  
  303.     // }}}
  304.     // {{{ prepare()
  305.  
  306.     /**
  307.      * Prepares a query for multiple execution with execute().  With
  308.      * oci8, this is emulated.
  309.      * @param $query query to be prepared
  310.      *
  311.      * @return DB statement resource
  312.      */
  313.     function prepare($query) {
  314.         $tokens = split('[\&\?]', $query);
  315.         $token = 0;
  316.         $types = array();
  317.         for ($i = 0; $i < strlen($query); $i++) {
  318.             switch ($query[$i]) {
  319.                 case '?':
  320.                     $types[$token++] = DB_PARAM_SCALAR;
  321.                     break;
  322.                 case '&':
  323.                     $types[$token++] = DB_PARAM_OPAQUE;
  324.                     break;
  325.             }
  326.         }
  327.         $binds=sizeof($tokens)-1;
  328.         for ($i=0;$i<$binds;$i++) {
  329.             $newquery.=$tokens[$i].":bind".$i;
  330.         }
  331.         $newquery.=$tokens[$i];
  332.         $this->last_query = $query;
  333.         $stmt=OCIParse($this->connection,$newquery);
  334.         $this->prepare_types[$stmt] = $types;
  335.         $this->select_query[$stmt] = preg_match('/(SELECT|SHOW)/i', $newquery);
  336.         return $stmt;
  337.     }
  338.  
  339.     // }}}
  340.     // {{{ execute()
  341.  
  342.     /**
  343.      * Executes a DB statement prepared with prepare().
  344.      *
  345.      * @param $stmt a DB statement resource (returned from prepare())
  346.      * @param $data data to be used in execution of the statement
  347.      *
  348.      * @return int returns an oci8 result resource for successful
  349.      * SELECT queries, DB_OK for other successful queries.  A DB error
  350.      * code is returned on failure.
  351.      */
  352.     function execute($stmt, $data = false) {
  353.         $types=&$this->prepare_types[$stmt];
  354.         if (($size=sizeof($types))!=sizeof($data)) {
  355.             return $this->raiseError();
  356.         }
  357.         for ($i=0;$i<$size;$i++) {
  358.             if (is_array($data)) {
  359.                 $pdata[$i]=$data[$i];
  360.             }
  361.             else {
  362.                 $pdata[$i]=$data;
  363.             }
  364.             if ($types[$i]==DB_PARAM_OPAQUE) {
  365.                 $fp = fopen($pdata[$i], "r");
  366.                 $pdata = '';
  367.                 if ($fp) {
  368.                     while (($buf = fread($fp, 4096)) != false) {
  369.                         $pdata[$i] .= $buf;
  370.                     }
  371.                 }
  372.             }
  373.             if (!OCIBindByName($stmt,":bind".$i,$pdata[$i],-1)) {
  374.                 return $this->raiseError();
  375.             }
  376.         }
  377.         if ($this->autoCommit) {
  378.             $success=OCIExecute($stmt,OCI_COMMIT_ON_SUCCESS);
  379.         }
  380.         else {
  381.             $success=OCIExecute($stmt,OCI_DEFAULT);
  382.         }
  383.         if (!$success) {
  384.             return $this->raiseError();
  385.         }
  386.         $this->last_stmt=$stmt;
  387.         if ($this->select_query[$stmt]) {
  388.             return $stmt;
  389.         }
  390.         else {
  391.             return $DB_OK;
  392.         }
  393.     }
  394.  
  395.     // }}}
  396.     // {{{ autoCommit()
  397.  
  398.     /**
  399.      * Enable/disable automatic commits
  400.      * 
  401.      * @param $onoff true/false whether to autocommit
  402.      */
  403.     function autoCommit($onoff = false) {
  404.         if (!$onoff) {
  405.             $this->autoCommit=0;
  406.         }
  407.         else {
  408.             $this->autoCommit=1;
  409.         }
  410.         return DB_OK;
  411.     }
  412.  
  413.     // }}}
  414.     // {{{ commit()
  415.  
  416.     /**
  417.      * Commit transactions on the current connection
  418.      *
  419.      * @return DB_ERROR or DB_OK
  420.      */
  421.     function commit() {
  422.         $result = OCICommit($this->connection);
  423.         if (!$result) {
  424.             return $this->raiseError();
  425.         }
  426.         return DB_OK;
  427.     }
  428.  
  429.     // }}}
  430.     // {{{ rollback()
  431.  
  432.     /**
  433.      * Roll back all uncommitted transactions on the current connection.
  434.      *
  435.      * @return DB_ERROR or DB_OK
  436.      */
  437.     function rollback() {
  438.         $result = OCIRollback($this->connection);
  439.         if (!$result) {
  440.             return $this->raiseError();
  441.         }
  442.         return DB_OK;
  443.     }
  444.  
  445.     // }}}
  446.     // {{{ affectedRows()
  447.  
  448.     /**
  449.      * Gets the number of rows affected by the last query.
  450.      * if the last query was a select, returns 0.
  451.      *
  452.      * @return number of rows affected by the last query or DB_ERROR
  453.      */
  454.     function affectedRows() {
  455.         if ($this->last_stmt === false) {
  456.             return $this->raiseError();
  457.         }
  458.         $result = OCIRowCount($this->last_stmt);
  459.         if ($result === false) {
  460.              return $this->raiseError();
  461.         }
  462.         return $result;
  463.     }
  464.  
  465.     // }}}
  466.  
  467. }
  468.  
  469. // Local variables:
  470. // tab-width: 4
  471. // c-basic-offset: 4
  472. // End:
  473. ?>
  474.